package com.example.gradu.graduationproject.service.impl;

import com.example.gradu.graduationproject.domain.AttentionUser;
import com.example.gradu.graduationproject.domain.Blog;
import com.example.gradu.graduationproject.domain.Comment;
import com.example.gradu.graduationproject.mapper.AttentionUserMapper;
import com.example.gradu.graduationproject.mapper.BlogMapper;
import com.example.gradu.graduationproject.mapper.CommentMapper;
import com.example.gradu.graduationproject.mapper.UserMapper;
import com.example.gradu.graduationproject.service.BlogService;
import com.example.gradu.graduationproject.util.R;
import com.example.gradu.graduationproject.vo.BlogRecommend;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * (Blog)表服务实现类
 *
 * @author makejava
 * @since 2025-03-02 17:04:45
 */
@Service("blogService")
public class BlogServiceImpl implements BlogService {
    @Resource
    private BlogMapper blogMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private CommentMapper commentMapper;
    @Resource
    private AttentionUserMapper attentionUserMapper;

    /**
     * 通过ID查询单条数据
     *
     * @param blogid 主键
     * @return 实例对象
     */
    @Override
    public R queryById(Integer blogid) {
        return R.ok().setData(this.blogMapper.queryById(blogid));
    }

    /**
     * 全查询
     *
     * @param blog 筛选条件
     * @return 查询结果
     */
    @Override
    public R queryAll(Blog blog) {
        List<Blog> blogs = this.blogMapper.queryAll(blog);

        // 处理转发型博文
        for (Blog b : blogs) {
            //  originalBlogId == -1 代表这个博客是原创型博文，不是转发型博文
            if(b.getOriginalBlogId()!=null && b.getOriginalBlogId() != -1) {
                b = buildRelayBlog(b);
            }
        }

        return R.ok().setData(blogs);
    }

    /**
     * 递归构建转发内容
     */
    String buildRelayContent(Integer originalBlogId) {
        StringBuilder relayContentBuilder = new StringBuilder();

        while (originalBlogId != -1){
            Blog originalBlog = blogMapper.queryById(originalBlogId);
            if(originalBlog == null) break;

            String authorName = userMapper.queryById(originalBlog.getUserid()).getUsername();
            relayContentBuilder.insert(0,"//@"+authorName+": "+originalBlog.getBlogText());
            originalBlogId = originalBlog.getOriginalBlogId();
        }
        return relayContentBuilder.toString();
    }

    /**
     * 重构转发型博文
     */
    Blog buildRelayBlog(Blog presentBlog){
        Blog relayBlog = presentBlog;  // 转发型博文
        StringBuilder relayContentBuilder = new StringBuilder();  //所有转发内容
        relayContentBuilder.insert(0,presentBlog.getBlogText());   //  第一个转发区展示自己的转发文本
        Integer originalBlogId = presentBlog.getOriginalBlogId();

        while (originalBlogId != -1){
            Blog originalBlog = blogMapper.queryById(originalBlogId);
            if(originalBlog == null ) break;
            if(originalBlog.getOriginalBlogId() == -1) {
                relayBlog.setBlogTitle(originalBlog.getBlogTitle());
                relayBlog.setAiSummary(originalBlog.getAiSummary());
                relayBlog.setBlogText(originalBlog.getBlogText());
                relayBlog.setBlogPhotoSrc(originalBlog.getBlogPhotoSrc());
                relayBlog.setDirectorySrc(originalBlog.getDirectorySrc());
                relayBlog.setRelayContent(relayContentBuilder.toString());
                break;
            }
            String authorName = userMapper.queryById(originalBlog.getUserid()).getUsername();
            relayContentBuilder.append("//@"+authorName+": "+originalBlog.getBlogText());
            originalBlogId = originalBlog.getOriginalBlogId();
        }

        return relayBlog;
    }

    /**
     * 新增数据
     *
     * @param blog 实例对象
     * @return 实例对象
     */
    @Override
    public R insert(Blog blog) {
        this.blogMapper.insert(blog);
        return R.ok().setData(blog);
    }

    /**
     * 修改数据
     *
     * @param blog 实例对象
     * @return 实例对象
     */
    @Override
    public R update(Blog blog) {
        this.blogMapper.update(blog);
        return R.ok().setData(this.queryById(blog.getBlogid()));
    }

    /**
     * 通过主键删除数据
     *
     * @param blogid 主键
     * @return 是否成功
     */
    @Override
    public R deleteById(Integer blogid) {
        boolean del = this.blogMapper.deleteById(blogid) > 0;
        return R.ok().setData(del);
    }

    /**
     * 根据用户id，返回推荐列表
     * @param userid 用户id
     * @param blog 博文筛选条件，这里通常为空
     * @return 推荐列表
     */
   @Override
   public  R queryAllRecommend(Blog blog,Integer userid){
       blog.setUserid(null);
       List<Blog> blogs = this.blogMapper.queryAll(blog);

//       System.out.println(blog);
//       System.out.println(blogs);
       List<BlogRecommend> blogRecommendList = new ArrayList<>();

       // 处理转发型博文
       for (Blog b : blogs) {
           //  originalBlogId == -1 代表这个博客是原创型博文，不是转发型博文
           if(b.getOriginalBlogId()!=null && b.getOriginalBlogId() != -1) {
               b = buildRelayBlog(b);
           }
           // 计算推荐分数
           double score = calculateRecommendWeight(b,userid);

           // 构建BlogRecommend对象
           BlogRecommend recommend = new BlogRecommend(b,score);
           blogRecommendList.add(recommend);
       }
       // 按推荐分数从大到小排序
       blogRecommendList.sort((b1,b2) -> Double.compare(b2.getRecommendScore(), b1.getRecommendScore()));
       // 将返回结果转化为Blog列表，以损失推荐分数属性为代价
       List<Blog> blogList = blogRecommendList.stream()
               .map(blogRecommend -> (Blog)blogRecommend) // 转换为Blog类型
               .collect(Collectors.toList());
        return R.ok().setData(blogList);
    }

    /**
     * 计算该博文的推荐分数
     * @param blog 博文
     * @param userid 刷推荐主页的博主的id
     * @return 推荐分数
     */
    public double calculateRecommendWeight(Blog blog,Integer userid){
//       根据博客ID查询评论数
        Comment query = new Comment();
        query.setBlogid(blog.getBlogid());
        Long commentCount = this.commentMapper.count(query);
        double commentWeight = commentCount * 5.0;
//       计算时间权重：最近的博客权重更高
        double timeWeight = 0.0;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        try{
            Date lastModified = sdf.parse(blog.getBlogUpdated());
            long diffInMs = new Date().getTime() - lastModified.getTime();
            double diffInDays = diffInMs / (1000.0 * 60 * 60 * 24);
//            时间衰减函数：今天发布的得100分，随着天数增长，权重逐渐降低
            timeWeight = 100.0 /(diffInDays +1.0);
        }catch (ParseException e){
            e.printStackTrace();
        }
//    好友关系加成
        AttentionUser attentionUser = new AttentionUser();
        attentionUser.setUserid(userid);  //博主id
        attentionUser.setUseridAtten(blog.getUserid());  //改博文发布者的userid
        boolean isFriend = this.attentionUserMapper.count(attentionUser) > 0;
        double friendsBonus = isFriend ?20.0:0.0;
//        各权重：各部分相加
        double totalWeight = timeWeight + commentWeight + friendsBonus;
//        System.out.println(blog.getBlogTitle());
//        System.out.println(totalWeight);
        return totalWeight;
    }
}

